package com.huayue.aop;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.huayue.annotation.LogAnno;
import com.huayue.entity.Logs;
import com.huayue.entity.User;
import com.huayue.service.LogsService;

/**
 * 通过注解向数据库写入系统操作日志
 * 
 */
@Component
@Aspect
public class LogsAop {

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private LogsService svc;

    /**
     * 环绕通知记录日志通过注解匹配到需要增加日志功能的方法
     *
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("@annotation(com.huayue.annotation.LogAnno)")
    public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
        // 1.方法执行前的处理，相当于前置通知
        // 获取方法签名
        MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
        // 获取方法
        Method method = methodSignature.getMethod();
        // 获取方法上面的注解
        LogAnno logAnno = method.getAnnotation(LogAnno.class);
        // 获取操作描述的属性值
        String operateType = logAnno.operateType();
        // 创建一个日志对象(准备记录日志)
        Logs logs = new Logs();
        // 操作说明
        logs.setOperatetype(operateType);
        // 备注设置获取参数 -序列化器，当没有字段时不执行JSON.toJSONString()，避免没有字段报错
        String remark = JSON.toJSONString(pjp.getArgs(), SerializerFeature.IgnoreNonFieldGetter);
        // 当备注信息超过1000个字符则截取前1000个，避免过长无法写入数据库
        if (remark.length() >= 1000) {
            remark = remark.substring(0, 999);
        }
        logs.setRemark(remark);
        // 获取session中的user对象进而获取操作人名字
        User user = null;
        // 找回密码时session中不存在用户信息，更改备注信息为找回密码
        if (operateType.indexOf("找回密码") != -1) {
            user = new User();
            user.setRealname("找回密码");
        } else {
            user = (User)request.getSession().getAttribute("USER");
        }

        logs.setOperateor(user.getRealname());

        Object result = null;
        try {
            // 让代理方法执行
            result = pjp.proceed();
            // 2.后置通知(方法成功执行之后走这里)
            logs.setIs_status(1);
        } catch (Exception e) {
            // 3.异常通知部分
            logs.setIs_status(0);
        } finally {
            // 4.相当于最终通知 添加日志记录
            svc.insert(logs);
        }
        return result;
    }
}
